package com.lzx.lizhenxing.pay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.lzx.lizhenxing.pay.config.AliPayProperties;
import com.lzx.lizhenxing.pay.param.PayParam;
import com.lzx.lizhenxing.pay.service.PayService;
import com.lzx.lizhenxing.pay.websocket.WebSocket;
import com.lzx.lizhenxing.user.service.UserOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Service("aliPayServiceImpl")
@Slf4j
public class AliPayServiceImpl implements PayService {

    @Resource
    private AlipayClient alipayClient;

    @Resource
    private AliPayProperties aliPayProperties;

    @Resource
    private UserOrderService userOrderService;

    @Resource
    private WebSocket webSocket;

    @Override
    public String createPayOrder(PayParam payParam) {
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        // 后台系统根据业务生成的订单编号
        model.setOutTradeNo(payParam.getTradeNo());
        // 支付金额
        model.setTotalAmount(payParam.getTotalAmount().toString());
        // 支付主题
        model.setSubject(payParam.getSubject());
        request.setBizModel(model);
        // 设置回调地址,支付宝用来通知后端程序支付成功还是失败
        // 但是这个地址不能设置为localhost，这样的话支付宝不能访问，需要内网穿透，使得支付宝能访问自己的主机
        request.setNotifyUrl(aliPayProperties.getNotifyUrl());
        AlipayTradePrecreateResponse response = null;
        try {
            // 向支付宝发送支付请求 返回包含二维码路径
            response = alipayClient.execute(request);
            System.out.println(response.getBody());
            if (response.isSuccess()) {
                // 返回二维码路径
                System.out.println("调用成功");
                return response.getQrCode();
            } else {
                throw new RuntimeException("调用失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("调用支付接口失败");
        }

    }

    @Override
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }
        // 针对支付宝，回调路径中自定义增加的参数，进行验签时，会失败，所以需要手动删除
        map.remove("orderNo");
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表
        //支付宝交易号
        String tradeNo = request.getParameter("trade_no");
        //获取总金额
        String totalFee = request.getParameter("total_amount");
        //获取订单号
        String orderNo = request.getParameter("out_trade_no");
        //获取交易状态
        String tradeStatus = request.getParameter("trade_status");
        log.info("支付宝异步回调交易状态trade_status：" + tradeStatus);

        //验证签名
        boolean signVerified = false;
        try {
            signVerified = AlipaySignature.rsaCheckV1(map,
                    aliPayProperties.getAlipayPublicKey(),
                    aliPayProperties.getCharset(),
                    aliPayProperties.getSignType());
            log.info("支付宝异步回调方法：验签结果" + signVerified);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return;
        }
        if (signVerified) {
            try {
                if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISH".equals(tradeStatus)) {
                    BigDecimal totalFees = new BigDecimal(totalFee);
                    // 支付后业务处理
                    /**
                     *  1.订单设置为已支付
                     *  2.给配送员生成任务单
                     *
                     */
                    userOrderService.dealOrder(orderNo);
                } else {
                    return;
                }
                log.info("支付成功异步回调success");
                // 告诉前端可以关闭二维码
                webSocket.sendMessage("true");
                //该语句不要修改或删除,商户通过返回success告诉支付宝支付成功，否则支付宝会一直回调
                response.getOutputStream().println("success");
                response.getOutputStream().close();
            } catch (Exception e) {
                e.printStackTrace();
                log.info("支付成功异步回调异常:" + e.getMessage());
            }
        } else {
            log.info("支付成功异步回调fail");
            // 告诉前端支付异常
            webSocket.sendMessage("false");
            try {
                response.getOutputStream().println("fail");
                response.getOutputStream().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
